package com.douqu.game.core.entity.battle;

import com.douqu.game.core.controller.MonsterController;
import com.douqu.game.core.e.E_BattleAObjectStatus;
import com.douqu.game.core.entity.Level;
import com.douqu.game.core.entity.StarCheck;
import com.douqu.game.core.entity.common.CommonData;
import com.douqu.game.core.entity.InitData;
import com.douqu.game.core.controller.BattleParentController;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.controller.SpriteController;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.sprite.Card;
import com.douqu.game.core.entity.sprite.CardLv;
import com.douqu.game.core.entity.sprite.CardQuality;
import com.douqu.game.core.entity.sprite.Player;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.util.Utils;
import org.apache.log4j.Logger;

import javax.xml.crypto.Data;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 精灵战斗数据类
 * Created by bean on 2017/7/25.
 */
public class SpriteBattleTmp implements Serializable {

    protected static final long serialVersionUID = 1L;

    Logger logger = Logger.getLogger(this.getClass());

    protected BattleParentController battleController;

    protected SpriteController spriteController;

    /**
     * 对手
     */
    protected SpriteBattleTmp targetBattleTmp;


    /**
     * 卡牌列表
     */
    protected List<Card> cardList;

    protected Map<Integer, Card> cardMap;


    /**
     * 队伍编号
     */
    protected int teamNo;

    /**
     * 主将
     */
    protected BattleAObject masterSoldier;

    /**
     * 召唤出来的兵
     */
    protected List<BattleAObject> soldierList;

    /**
     * 准备
     */
    protected boolean ready;


    /**
     * 当前水晶值
     */
    protected int curCrystal;

    /**
     * 最大水晶值
     */
    protected int maxCrystal;

    /**
     * 水晶成长
     */
    protected CommonData[] crystalGrows;

    /**
     * 是否是AI
     */
    protected boolean isAI;

    /**
     * 公共CD
     */
    protected int publicCDTime;

    /**
     * 当前获得的星星
     */
    public int star;



    public void init(SpriteController spriteController, BattleAObject masterSoldier, int teamNo)
    {
        InitData initData = DataFactory.getInstance().getInitData();
        this.curCrystal = initData.curCrystal;
        this.maxCrystal = initData.maxCrystal;
        this.crystalGrows = initData.crystalGrow;

        this.spriteController = spriteController;
        this.masterSoldier = masterSoldier;
        this.teamNo = teamNo;
        this.soldierList = new CopyOnWriteArrayList<>();

        if(spriteController instanceof PlayerController)
        {
            PlayerController playerController = (PlayerController) spriteController;
            BagInfo bagInfo = (BagInfo) playerController.getPlayer().getExtInfo(BagInfo.class);

            cardList = bagInfo.getBattleCardList();
            cardMap = new ConcurrentHashMap<>();
            for(Card card : cardList)
            {
                cardMap.put(card.getId(), card);
            }

            //打乱顺序
            Collections.shuffle(cardList);

            isAI = !playerController.isPlayer();
        }
        else if(spriteController instanceof MonsterController)
        {
            Level level = ((MonsterController) spriteController).getLevel();
            if(level != null)
            {
                cardList = new CopyOnWriteArrayList<>();
                for(CommonData cardData : level.cards)
                {
                    Card card = DataFactory.getInstance().getGameObject(DataFactory.CARD_KEY, cardData.id);
                    Card newCard = (Card) Card.cloneObject(card);
                    newCard.lv = cardData.value;
                    cardList.add(newCard);
                }

                cardMap = new ConcurrentHashMap<>();
                for(Card card : cardList)
                {
                    cardMap.put(card.getId(), card);
                }

                //打乱顺序
                Collections.shuffle(cardList);
            }
            isAI = true;
        }
    }

    /**
     *
     * @param currentTime 当前时间
     * @param battleTime 当前战斗持续时间
     * @param updateTime 更新频率
     */
    public void update(long currentTime, int battleTime, int updateTime)
    {
        if(publicCDTime > 0)
        {
            publicCDTime -= updateTime;
            publicCDTime = publicCDTime < 0 ? 0 : publicCDTime;
        }

        if(!isMaxCrystal())
        {
//            logger.info(spriteController.getName() + " 计算水晶成长，当前战斗运行时间:" + battleTime);
            if(crystalGrows != null && crystalGrows.length > 0)
            {
                for(CommonData data : crystalGrows)
                {
                    if(battleTime < data.id)
                    {
                        //在此区间的成长规则
                        if(battleTime % data.value == 0)
                        {
                            curCrystal++;
                        }
                        break;
                    }
                }
            }
//            logger.info("当前水晶："+curCrystal);
        }

        if(isAI)
        {
            //出牌AI
            if(checkAI())
                return;
        }

        //检测主将攻击
        masterSoldier.checkDefaultSkillTarget(currentTime);

        if(battleController.isEnd())
            return;

        masterSoldier.update(updateTime);

        if(battleController.isEnd())
            return;

        //小兵前进
        for(BattleAObject aObject : soldierList)
        {
//                logger.info("soldier:" + soldier);
            if(aObject.getStatus() == E_BattleAObjectStatus.GOING)
            {
//                    logger.info(soldier.getTeamNo() + "  " + soldier.getId()+"  向前走");
                aObject.go();
            }
        }

        //检测小兵攻击
        for(BattleAObject soldier : soldierList)
        {
            soldier.checkDefaultSkillTarget(currentTime);
            if(battleController.isEnd())
                return;
            soldier.update(updateTime);
            if(battleController.isEnd())
                return;
        }



    }



    public void addStar(int value)
    {
        star += value;
        star = star < 0 ? 0 : star;
    }







    public void addCrystal(int value)
    {
        curCrystal += value;
        curCrystal = curCrystal < 0 ? 0 : curCrystal;
        curCrystal = curCrystal > maxCrystal ? maxCrystal : curCrystal;
    }


    public boolean checkAI()
    {
        return false;
    }

    public boolean isMaxCrystal()
    {
        return curCrystal >= maxCrystal;
    }

    public BattleAObject getMaxFCSoldier()
    {
        return Utils.getMaxGameObject(soldierList, new Comparator<BattleAObject>() {
            @Override
            public int compare(BattleAObject o1, BattleAObject o2) {
                return o1.fc - o2.fc;
            }
        });
    }

    public Card getMaxFCCard()
    {
        return Utils.getMaxGameObject(cardList, new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                CardLv cardLv1 = DataFactory.getInstance().getGameObject(DataFactory.CARD_LV_KEY, o1.lv);
                CardLv cardLv2 = DataFactory.getInstance().getGameObject(DataFactory.CARD_LV_KEY, o2.lv);
                return cardLv1.getByQuality(o1.quality).fc - cardLv2.getByQuality(o2.quality).fc;
            }
        });
    }

    public BattleAObject getMaxLossHPSoldier()
    {
        return Utils.getMaxGameObject(soldierList, new Comparator<BattleAObject>() {
            @Override
            public int compare(BattleAObject o1, BattleAObject o2) {
                return o1.getLossHp() - o2.getLossHp();
            }
        });
    }


    public void sendMsg(int code, byte[] data)
    {
        if(spriteController != null)
            spriteController.sendMsg(code, data);
    }


    /**
     * 获取战斗卡牌
     * @return
     */
    public Card getCardById(int id)
    {
        return cardMap.get(id);
    }

    /**
     * 上战场
     * @param card
     */
    public void toBattlefield(Card card)
    {
        cardList.remove(card);
        cardMap.remove(card.getId());
    }


    /**
     * 是否死亡
     * @return
     */
    public boolean isDie()
    {
        return masterSoldier.isDie();
    }

    public int getPublicCDTime()
    {
        return publicCDTime;
    }

    public void setPublicCDTime(int time)
    {
        this.publicCDTime = time;
    }


    public void addBattleSoldier(BattleAObject battleAObject)
    {
        soldierList.add(battleAObject);
    }

    public void addSoldier(BattleAObject soldier)
    {
        soldierList.add(soldier);
    }

    public void removeSoldier(BattleAObject soldier)
    {
        soldierList.remove(soldier);
    }

    public BattleParentController getBattleParent() {
        return battleController;
    }

    public void setBattleParent(BattleParentController battleController) {
        this.battleController = battleController;
    }

    public int getTeamNo() {
        return teamNo;
    }

    public SpriteController getSpriteController() {
        return spriteController;
    }

    public List<BattleAObject> getSoldierList() {
        return soldierList;
    }

    public boolean isReady() {
        return ready;
    }

    public void setReady(boolean ready) {
        this.ready = ready;
    }

    public int getCurCrystal() {
        return curCrystal;
    }

    public int getMaxCrystal() {
        return maxCrystal;
    }

    public boolean isAI() {
        return isAI;
    }

    public void setAI(boolean isAI) {
        this.isAI = isAI;
    }

    public SpriteBattleTmp getTargetBattleTmp() {
        return targetBattleTmp;
    }

    public void setTargetBattleTmp(SpriteBattleTmp targetBattleTmp) {
        this.targetBattleTmp = targetBattleTmp;
    }

    public BattleAObject getMasterSoldier() {
        return masterSoldier;
    }

    public List<Card> getCardList() {
        return cardList;
    }


    @Override
    public String toString() {
        return "{" +
                ", teamNo=" + teamNo +
                ", masterSoldier=" + masterSoldier +
                ", soldierList=" + soldierList +
                ", curCrystal=" + curCrystal +
                ", maxCrystal=" + maxCrystal +
                ", isAI=" + isAI +
                '}';
    }
}
